tree grammar inputAST;

options {
  tokenVocab = input;
  ASTLabelType = CommonTree;
}

@header {
package compiler.antlr;
import compiler.grammar.*;
import java.util.ArrayList;
}


grammarSpec returns [Grammar result]
	: ^(GRAMMAR terminals=regularExprDecls nonTerminals=bnfDecls) { $result = new Grammar(terminals,nonTerminals); }
	;
	
regularExprDecls returns [ArrayList<Terminal> result]
	@init{$result = new ArrayList<Terminal>();}
	: (reg=regularExprDecl { $result.add(reg); } ) +	
	;
	
bnfDecls returns [ArrayList<NonTerminal> result]
	@init{$result = new ArrayList<NonTerminal>();}
	: (bnf=bnfDecl { $result.add(bnf); } ) +
	;

regularExprDecl returns [Terminal result]
	: ^(REDECL id=REID str=StringLiteral) { $result = new Terminal($id.text,$str.text); }
	;

bnfDecl returns [NonTerminal result]
	: ^(BNFDECL id=BNFID prods=bnfProductions[$id.text]) { $result = new NonTerminal($id.text,prods); }
	;
	
bnfProductions[String name] returns [ArrayList<Production> result]
	@init{$result = new ArrayList<Production>();}
	: (^(PROD prod=bnfProduction[name] { $result.add(prod); } ))+ 
	;
		
bnfProduction[String name] returns [Production result]
	@init{$result = new Production(name);}
	: ( id=( BNFID | REID ) { $result.add($id.text); } )*
	| EPSILON // empty production
	;	
	
